﻿using System;
using System.Windows;
using System.Windows.Media;

namespace WickedFlame.Core.Shapes
{
    public abstract class RectangleBase : VectorShape
    {
        Rect _rectangle;

        public RectangleBase()
            : this(0, 0, 1, 1)
        {
        }

		public RectangleBase(Point point, Size size)
			: this(point.X, point.Y, size.Width, size.Height)
		{
		}


        public RectangleBase(double x, double y, double width, double height)
		{
			_rectangle = new Rect(x, y, width, height);
		}

        public virtual Rect Rectangle
        {
            get
            {
                return _rectangle;
            }
            set
            {
                _rectangle = value;
            }
        }

        public override Rect Bounds
        {
            get
            {
                return _rectangle;
            }
        }

        /// <summary>
        /// Get number of trackers
        /// </summary>
        public override int TrackerCount
        {
            get
            {
                return 4;
            }
        }

        double _rotation;
        public double Rotation
        {
            get
            {
                return _rotation;
            }
            set
            {
                var tmp = value;

                if (value > 360)
                    tmp = 0;
                if (value < 0)
                    tmp = 0;

                _rotation = tmp;

                NotifyPropertyChanged("Rotation");

                Invalidate();
            }
        }

        /// <summary>
        /// Get tracker point
        /// </summary>
        /// <param name="trackerNo"></param>
        /// <returns></returns>
        public override Point GetTracker(int trackerNo)
        {
            double x, y;
            x = _rectangle.X;
            y = _rectangle.Y;

            switch (trackerNo)
            {
                case 1:
                    x = _rectangle.X;
                    y = _rectangle.Y;
                    break;
                case 2:
                    x = _rectangle.Right;
                    y = _rectangle.Y;
                    break;
                case 3:
                    x = _rectangle.Right;
                    y = _rectangle.Bottom;
                    break;
                case 4:
                    x = _rectangle.X;
                    y = _rectangle.Bottom;
                    break;
            }

            return new Point(x, y);
        }

        ///// <summary>
        ///// Hit test
        ///// </summary>
        ///// <param name="point"></param>
        ///// <returns></returns>
        //public override int HitTestInt(Point point)
        //{
        //    if (IsSelected)
        //    {
        //        for (int i = 1; i <= TrackerCount; i++)
        //        {
        //            if (GetTrackerRectangle(i).Contains(point))
        //                return i;
        //        }
        //    }

        //    if (PointInObject(point))
        //        return 0;

        //    return -1;
        //}

        protected override bool PointInObject(Point point)
        {
            return _rectangle.Contains(point);
        }

        /// <summary>
        /// Move tracker to new point (resizing)
        /// </summary>
        /// <param name="point"></param>
        /// <param name="trackerNo"></param>
        public override void MoveTracker(Point point, int trackerNo)
        {
            double left = _rectangle.Left;
            double top = _rectangle.Top;
            double right = _rectangle.Right;
            double bottom = _rectangle.Bottom;

            switch (trackerNo)
            {
                case 1:
                    left = point.X;
                    top = point.Y;
                    break;
                case 2:
                    right = point.X;
                    top = point.Y;
                    break;
                case 3:
                    right = point.X;
                    bottom = point.Y;
                    break;
                case 4:
                    left = point.X;
                    bottom = point.Y;
                    break;
            }

            SetRectangle(left, top, right - left, bottom - top);

            CallChangedHandler();
        }

        public override void MoveTracker(int tracker, double deltaX, double deltaY)
        {
            double left = _rectangle.Left;
            double top = _rectangle.Top;
            double right = _rectangle.Right;
            double bottom = _rectangle.Bottom;

            switch (tracker)
            {
                case 1:
                    left += deltaX;
                    top += deltaY;
                    break;
                case 2:
                    right += deltaX;
                    top += deltaY;
                    break;
                case 3:
                    right += deltaX; ;
                    bottom += deltaY;
                    break;
                case 4:
                    left += deltaX;
                    bottom += deltaY;
                    break;
            }

            SetRectangle(left, top, right - left, bottom - top);

            CallChangedHandler();
        }

        protected void SetRectangle(double x, double y, double width, double height)
        {
            try
            {
                _rectangle.X = x;
                _rectangle.Y = y;
                _rectangle.Width = width;
                _rectangle.Height = height;

                this.Invalidate();
            }
            catch { }
        }

        public override void Move(double deltaX, double deltaY)
        {
            _rectangle.X += deltaX;
            _rectangle.Y += deltaY;
            this.Invalidate();

            CallMovedHandler();
        }

        /// <summary>
        /// Get cursor for the handle
        /// </summary>
        /// <param name="trackerNo"></param>
        /// <returns></returns>
        public override System.Windows.Input.Cursor GetTrackerCursor(int trackerNo)
        {
            switch (trackerNo)
            {
                case 1:
                    return System.Windows.Input.Cursors.SizeNWSE;
                case 2:
                    return System.Windows.Input.Cursors.SizeNESW;
                case 3:
                    return System.Windows.Input.Cursors.SizeNWSE;
                case 4:
                    return System.Windows.Input.Cursors.SizeNESW;
                default:
                    return System.Windows.Input.Cursors.Arrow;
            }
        }

        public override bool IntersectsWith(Rect rectangle)
        {
            return _rectangle.IntersectsWith(rectangle);
        }

        public override void DrawTracker(DrawingContext drawingContext, double scale)
        {
            Pen p = new Pen(Brushes.Blue, 1 / scale);
            Pen ps = new Pen(Brushes.Black, 2 / scale);

            double halfPenWidth = 0.5 / 2;

            // Create a guidelines set
            GuidelineSet guidelines = new GuidelineSet();
            guidelines.GuidelinesX.Add(Rectangle.Left + halfPenWidth);
            guidelines.GuidelinesX.Add(Rectangle.Right + halfPenWidth);
            guidelines.GuidelinesY.Add(Rectangle.Top + halfPenWidth);
            guidelines.GuidelinesY.Add(Rectangle.Bottom + halfPenWidth);

            drawingContext.PushGuidelineSet(guidelines);

            drawingContext.DrawRectangle(
                Brushes.Transparent,
                new Pen(Brushes.Blue, 0.5 / scale),
                Rectangle);

            drawingContext.Pop();

            double r = 2.5;
            if (scale != 0)
                r = 2.5 / scale;

            if (!(SelectedTracker == 1))
                drawingContext.DrawEllipse(Brushes.LightBlue, p, new Point(Rectangle.X, Rectangle.Y), r, r);
            else
                drawingContext.DrawEllipse(Brushes.White, ps, new Point(Rectangle.X, Rectangle.Y), r, r);

            if (!(SelectedTracker == 2))
                drawingContext.DrawEllipse(Brushes.LightBlue, p, new Point(Rectangle.X + Rectangle.Width, Rectangle.Y), r, r);
            else
                drawingContext.DrawEllipse(Brushes.White, ps, new Point(Rectangle.X + Rectangle.Width, Rectangle.Y), r, r);

            if (!(SelectedTracker == 3))
                drawingContext.DrawEllipse(Brushes.LightBlue, p, new Point(Rectangle.X + Rectangle.Width, Rectangle.Y + Rectangle.Height), r, r);
            else
                drawingContext.DrawEllipse(Brushes.White, ps, new Point(Rectangle.X + Rectangle.Width, Rectangle.Y + Rectangle.Height), r, r);

            if (!(SelectedTracker == 4))
                drawingContext.DrawEllipse(Brushes.LightBlue, p, new Point(Rectangle.X, Rectangle.Y + Rectangle.Height), r, r);
            else
                drawingContext.DrawEllipse(Brushes.White, ps, new Point(Rectangle.X, Rectangle.Y + Rectangle.Height), r, r);
        }
    }
}
